package com.wusiwei.controller;

import com.wusiwei.common.Result;
import com.wusiwei.entity.Receipt;
import com.wusiwei.service.ReceiptService;
import com.wusiwei.vo.ReceiptStatistics;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 收货单控制器
 */
@RestController
@RequestMapping("/api/receipts")
@RequiredArgsConstructor
@Slf4j
@Tag(name = "收货单管理", description = "收货单管理相关的API接口")
public class ReceiptController {

    private final ReceiptService receiptService;

    /**
     * 获取所有收货单
     *
     * @return 收货单列表
     */
    @GetMapping
    @Operation(summary = "获取所有收货单", description = "获取系统中所有收货单列表")
    public Result<List<Receipt>> getAllReceipts() {
        try {
            List<Receipt> receipts = receiptService.getAllReceipts();
            return Result.success(receipts);
        } catch (Exception e) {
            log.error("获取所有收货单失败", e);
            return Result.error("获取收货单列表失败: " + e.getMessage());
        }
    }

    /**
     * 根据ID获取收货单
     *
     * @param id 收货单ID
     * @return 收货单信息
     */
    @GetMapping("/{id}")
    @Operation(summary = "获取收货单详情", description = "根据ID获取收货单详细信息")
    public Result<Receipt> getReceiptById(@Parameter(description = "收货单ID") @PathVariable Long id) {
        try {
            Receipt receipt = receiptService.getReceiptById(id);
            if (receipt != null) {
                return Result.success(receipt);
            } else {
                return Result.error("收货单不存在");
            }
        } catch (Exception e) {
            log.error("获取收货单详情失败, ID: {}", id, e);
            return Result.error("获取收货单详情失败: " + e.getMessage());
        }
    }

    /**
     * 根据订单ID获取关联收货单
     *
     * @param orderId 订单ID
     * @return 收货单列表
     */
    @GetMapping("/order/{orderId}")
    @Operation(summary = "获取订单关联收货单", description = "根据订单ID获取关联的收货单列表")
    public Result<List<Receipt>> getReceiptsByOrderId(@Parameter(description = "订单ID") @PathVariable Long orderId) {
        try {
            List<Receipt> receipts = receiptService.getReceiptsByOrderId(orderId);
            return Result.success(receipts);
        } catch (Exception e) {
            log.error("获取订单关联收货单失败, 订单ID: {}", orderId, e);
            return Result.error("获取订单关联收货单失败: " + e.getMessage());
        }
    }

    /**
     * 创建收货单
     *
     * @param receipt 收货单信息
     * @return 创建的收货单
     */
    @PostMapping
    @Operation(summary = "创建收货单", description = "创建新的收货单记录")
    public Result<Receipt> createReceipt(@RequestBody Receipt receipt) {
        try {
            Receipt createdReceipt = receiptService.createReceipt(receipt);
            return Result.success(createdReceipt);
        } catch (Exception e) {
            log.error("创建收货单失败", e);
            return Result.error("创建收货单失败: " + e.getMessage());
        }
    }

    /**
     * 更新收货单
     *
     * @param id      收货单ID
     * @param receipt 更新的收货单信息
     * @return 更新后的收货单
     */
    @PutMapping("/{id}")
    @Operation(summary = "更新收货单", description = "根据ID更新收货单信息")
    public Result<Receipt> updateReceipt(@Parameter(description = "收货单ID") @PathVariable Long id, @RequestBody Receipt receipt) {
        try {
            Receipt updatedReceipt = receiptService.updateReceipt(id, receipt);
            if (updatedReceipt != null) {
                return Result.success(updatedReceipt);
            } else {
                return Result.error("收货单不存在");
            }
        } catch (Exception e) {
            log.error("更新收货单失败, ID: {}", id, e);
            return Result.error("更新收货单失败: " + e.getMessage());
        }
    }

    /**
     * 删除收货单
     *
     * @param id 收货单ID
     * @return 操作结果
     */
    @DeleteMapping("/{id}")
    @Operation(summary = "删除收货单", description = "根据ID删除收货单")
    public Result<Void> deleteReceipt(@Parameter(description = "收货单ID") @PathVariable Long id) {
        try {
            boolean success = receiptService.deleteReceipt(id);
            if (success) {
                return Result.success();
            } else {
                return Result.error("收货单不存在或删除失败");
            }
        } catch (Exception e) {
            log.error("删除收货单失败, ID: {}", id, e);
            return Result.error("删除收货单失败: " + e.getMessage());
        }
    }

    /**
     * 批量删除收货单
     *
     * @param ids 收货单ID列表
     * @return 操作结果
     */
    @DeleteMapping("/batch")
    @Operation(summary = "批量删除收货单", description = "批量删除多个收货单")
    public Result<Void> batchDeleteReceipt(@Parameter(description = "收货单ID列表") @RequestBody List<Long> ids) {
        try {
            boolean success = receiptService.batchDeleteReceipt(ids);
            if (success) {
                return Result.success();
            } else {
                return Result.error("部分或全部收货单删除失败");
            }
        } catch (Exception e) {
            log.error("批量删除收货单失败, IDs: {}", ids, e);
            return Result.error("批量删除收货单失败: " + e.getMessage());
        }
    }

    /**
     * 收货单验收
     *
     * @param id     收货单ID
     * @param status 验收状态
     * @return 更新后的收货单
     */
    @PutMapping("/{id}/accept")
    @Operation(summary = "收货单验收", description = "更新收货单的验收状态")
    public Result<Receipt> acceptReceipt(
            @Parameter(description = "收货单ID") @PathVariable Long id,
            @Parameter(description = "验收状态") @RequestParam String status) {
        try {
            Receipt receipt = receiptService.acceptReceipt(id, status);
            if (receipt != null) {
                return Result.success(receipt);
            } else {
                return Result.error("收货单不存在");
            }
        } catch (Exception e) {
            log.error("收货单验收失败, ID: {}, 状态: {}", id, status, e);
            return Result.error("收货单验收失败: " + e.getMessage());
        }
    }

    /**
     * 分页查询收货单
     *
     * @param pageNum       页码
     * @param pageSize      每页大小
     * @param receiptNumber 收货单号
     * @param supplierName  供应商
     * @param status        状态
     * @param startDate     开始日期
     * @param endDate       结束日期
     * @return 收货单分页结果
     */
    @GetMapping("/page")
    @Operation(summary = "分页查询收货单", description = "根据条件分页查询收货单")
    public Result<Object> getReceiptPage(
            @Parameter(description = "页码") @RequestParam(defaultValue = "1") int pageNum,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") int pageSize,
            @Parameter(description = "收货单号") @RequestParam(required = false) String receiptNumber,
            @Parameter(description = "供应商名称") @RequestParam(required = false) String supplierName,
            @Parameter(description = "收货单状态") @RequestParam(required = false) String status,
            @Parameter(description = "开始日期，格式：yyyy-MM-dd") @RequestParam(required = false) String startDate,
            @Parameter(description = "结束日期，格式：yyyy-MM-dd") @RequestParam(required = false) String endDate,
            @Parameter(description = "收货日期，格式：yyyy-MM-dd") @RequestParam(required = false) String receiptDate) {
        try {
            Object result = receiptService.getReceiptPage(pageNum, pageSize, receiptNumber, supplierName, status, startDate, endDate, receiptDate);
            return Result.success(result);
        } catch (Exception e) {
            log.error("分页查询收货单失败", e);
            return Result.error("分页查询收货单失败: " + e.getMessage());
        }
    }

    /**
     * 获取收货单状态统计
     *
     * @return 收货单状态统计
     */
    @GetMapping("/statistics/status")
    @Operation(summary = "获取收货单状态统计", description = "统计不同状态的收货单数量")
    public Result<ReceiptStatistics> getReceiptStatusStatistics() {
        try {
            ReceiptStatistics statistics = receiptService.getReceiptStatusStatistics();
            return Result.success(statistics);
        } catch (Exception e) {
            log.error("获取收货单状态统计失败", e);
            return Result.error("获取收货单状态统计失败: " + e.getMessage());
        }
    }

    /**
     * 导出收货单
     *
     * @param receiptNumber 收货单号
     * @param supplierName  供应商名称
     * @param status        状态
     * @param startDate     开始日期
     * @param endDate       结束日期
     * @return 导出的文件
     */
    @GetMapping("/export")
    @Operation(summary = "导出收货单", description = "将收货单数据导出为Excel文件")
    public ResponseEntity<?> exportReceipts(
            @Parameter(description = "收货单号") @RequestParam(required = false) String receiptNumber,
            @Parameter(description = "供应商名称") @RequestParam(required = false) String supplierName,
            @Parameter(description = "状态") @RequestParam(required = false) String status,
            @Parameter(description = "开始日期，格式：yyyy-MM-dd") @RequestParam(required = false) String startDate,
            @Parameter(description = "结束日期，格式：yyyy-MM-dd") @RequestParam(required = false) String endDate) {
        try {
            log.info("导出收货单数据, 收货单号: {}, 供应商: {}, 状态: {}, 日期范围: {} - {}",
                    receiptNumber, supplierName, status, startDate, endDate);

            // 获取当前认证用户
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication == null || !authentication.isAuthenticated() ||
                    authentication.getPrincipal().equals("anonymousUser")) {
                log.warn("导出收货单失败: 用户未认证");

                // 返回明确的401错误，前端不会尝试刷新token
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                headers.setCacheControl("no-cache, no-store, must-revalidate");

                return ResponseEntity
                        .status(HttpStatus.UNAUTHORIZED)
                        .headers(headers)
                        .body("{\"code\":401,\"message\":\"登录已过期，请重新登录后再尝试导出\",\"success\":false}");
            }

            log.info("授权用户: {}", authentication.getName());

            byte[] fileContent = receiptService.exportReceipts(receiptNumber, supplierName, status, startDate, endDate);

            if (fileContent == null || fileContent.length == 0) {
                log.warn("导出收货单数据为空");
                return ResponseEntity.status(HttpStatus.NO_CONTENT)
                        .contentType(MediaType.APPLICATION_JSON)
                        .body("{\"code\":204,\"message\":\"没有可导出的数据\",\"success\":false}");
            }

            log.info("成功生成导出文件，大小: {} 字节", fileContent.length);

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
            headers.setContentDispositionFormData("attachment", "receipts_" + System.currentTimeMillis() + ".xlsx");
            // 添加缓存控制和下载属性
            headers.setCacheControl("no-cache, no-store, must-revalidate");
            headers.setPragma("no-cache");
            headers.setExpires(0);

            log.info("导出收货单成功，返回Excel文件");

            return ResponseEntity.ok()
                    .headers(headers)
                    .body(fileContent);
        } catch (Exception e) {
            log.error("导出收货单失败: {}", e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .contentType(MediaType.APPLICATION_JSON)
                    .body("{\"code\":500,\"message\":\"导出收货单失败: " + e.getMessage() + "\",\"success\":false}");
        }
    }

    /**
     * 获取收货单总金额
     *
     * @return 收货单总金额
     */
    @GetMapping("/total-amount")
    @Operation(summary = "获取收货单总金额", description = "计算所有收货单的总金额")
    public Result<BigDecimal> getTotalReceiptAmount() {
        try {
            BigDecimal totalAmount = receiptService.getTotalReceiptAmount();
            return Result.success(totalAmount);
        } catch (Exception e) {
            log.error("获取收货单总金额失败", e);
            return Result.error("获取收货单总金额失败: " + e.getMessage());
        }
    }

    /**
     * 获取按供应商统计的收货单数据
     *
     * @param limit 限制返回的供应商数量
     * @return 按供应商统计的收货单数据
     */
    @GetMapping("/by-supplier")
    @Operation(summary = "按供应商统计收货单", description = "按供应商分组统计收货单数量和金额")
    public Result<List<Map<String, Object>>> getReceiptStatsBySupplier(
            @Parameter(description = "限制返回的供应商数量") @RequestParam(defaultValue = "10") Integer limit) {
        try {
            List<Map<String, Object>> statistics = receiptService.getReceiptStatsBySupplier(limit);
            return Result.success(statistics);
        } catch (Exception e) {
            log.error("按供应商统计收货单失败", e);
            return Result.error("按供应商统计收货单失败: " + e.getMessage());
        }
    }

    /**
     * 根据订单编号搜索收货单
     *
     * @param orderNumberData 包含订单编号的请求数据
     * @return 收货单列表
     */
    @PostMapping("/search")
    @Operation(summary = "根据订单编号搜索收货单", description = "根据订单编号查询关联的收货单")
    public Result<List<Receipt>> findReceiptsByOrderNumber(@RequestBody Map<String, String> orderNumberData) {
        try {
            String orderNumber = orderNumberData.get("orderNumber");
            if (orderNumber == null || orderNumber.trim().isEmpty()) {
                return Result.error("订单编号不能为空");
            }

            log.info("根据订单编号搜索收货单: {}", orderNumber);
            List<Receipt> receipts = receiptService.findByOrderNumber(orderNumber);

            if (receipts.isEmpty()) {
                log.info("未找到与订单编号 {} 关联的收货单", orderNumber);
                return Result.success(List.of());
            }

            log.info("找到 {} 条与订单编号 {} 关联的收货单", receipts.size(), orderNumber);
            return Result.success(receipts);
        } catch (Exception e) {
            log.error("根据订单编号搜索收货单失败", e);
            return Result.error("根据订单编号搜索收货单失败: " + e.getMessage());
        }
    }
} 